//	Copyright (C) 2007 Christian Martick, http://juhu-mac.blogspot.com
//
//	Permission is hereby granted, free of charge, to any person obtaining a copy
//	of this software and associated documentation files (the "Software"), to deal
//	in the Software without restriction, including without limitation the rights
//	to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
//	copies of the Software, and to permit persons to whom the Software is
//	furnished to do so, subject to the following conditions:
//
//	The above copyright notice and this permission notice shall be included in
//	all copies or substantial portions of the Software.
//
//	THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
//	IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
//	FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
//	AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
//	LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
//	OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
//	THE SOFTWARE.

#import "smcReadView.h"

#define kSmcButtonBarBasic 1
#define kSmcButtonBarAdd 2
#define kSmcButtonBarRemove 3
#define kSmcButtonBarTrash 4

extern NSString *kUIButtonBarButtonAction;
extern NSString *kUIButtonBarButtonInfo;
extern NSString *kUIButtonBarButtonInfoOffset;
extern NSString *kUIButtonBarButtonSelectedInfo;
extern NSString *kUIButtonBarButtonStyle;
extern NSString *kUIButtonBarButtonTag;
extern NSString *kUIButtonBarButtonTarget;
extern NSString *kUIButtonBarButtonTitle;
extern NSString *kUIButtonBarButtonTitleVerticalHeight;
extern NSString *kUIButtonBarButtonTitleWidth;
extern NSString *kUIButtonBarButtonType;

@implementation _smcAnotherBox

- (void) drawRect: (CGRect) rect
{
	[super drawRect: rect];
	
	// just draw another box
	CGColorRef lightgrey = [UIView colorWithRed: 0.95f green: 0.95f blue: 0.95f alpha: 1.0f];
	CGColorRef white = [UIView colorWithRed: 1.0f green: 1.0f blue: 1.0f alpha: 1.0f];
		
	CGContextSetFillColorWithColor(UICurrentContext(), white);
	UIBezierPath *bgPath = [UIBezierPath roundedRectBezierPath: CGRectMake (0.0f, 0.f, rect.size.width, rect.size.height )
    	withRoundedCorners: 15
    	withCornerRadius: 25.0f];
	[bgPath fill]; 
	
	CGContextSetFillColorWithColor(UICurrentContext(), lightgrey);
	bgPath = [UIBezierPath roundedRectBezierPath: CGRectMake (0.0f, 0.0f, rect.size.width, 85.0f )
    	withRoundedCorners: 3
    	withCornerRadius: 25.0f];
	[bgPath fill]; 
}
@end

@implementation smcReadView

#pragma mark the usual

- (void) dealloc 
{	
	[maps release];
	[progress release];
	[name release];
	[location release];
	[time release];
	[buttonBar release];
	[webView release];
	[_content release];
	[topBar release];
	[scrollView release];
	[box release];
	[super dealloc];
}

- initWithFrame: (CGRect) rect
{
	self = [super initWithFrame: rect];
	if (self != nil)
	{
		_content = nil;
		_jaiku = nil;
		
		// set color
		[self setBackgroundColor: [UIView colorWithRed: 0.0f green: 0.0f blue: 0.0f alpha: 1.0f]];
		
		// create scroll view
		scrollView = [[UIScroller alloc] initWithFrame: rect];
		[scrollView setShowScrollerIndicators: NO];
		
		// create box (will be scroller subview)
		box = [[_smcAnotherBox alloc] initWithFrame: CGRectMake (20.0f, 50.0f, [scrollView frame].size.width - 40.0f, 120.0f)];
		[box setAutoresizesSubviews: NO];
		
	/* 
			NOTE: using UIWebView
			relies on header hack - needs UIKeyboardInput.h (latest headers) and rename it to UIKeyboardInputProtocol.h
			and also remove Protocol behind DOMNode<>
	*/
		
		// works as display view for the text 
		webView = [[UIWebView alloc] initWithFrame: CGRectMake(0.0f, 85.0f, [box frame].size.width, [box frame].size.height - 20.0f)];
		[webView setUserStyleSheetLocation: [NSURL fileURLWithPath: 
			[[NSBundle mainBundle] pathForResource: @"stylesheet" ofType: @"css" inDirectory: @""]]];
			
		[(WebView *) [webView webView] setFrameLoadDelegate: self];
		[(WebView *) [webView webView] setPolicyDelegate: self];
		[(WebView *) [webView webView] setMaintainsBackForwardList: NO];
	
		// the icon
		icon = [[UIImageView alloc] initWithFrame:  CGRectMake(20.0f, 15.0f, 50.0f, 50.0f)];
		[icon setTapDelegate: self];
		
		// name, time, location and maps button
		name = [[UITextLabel alloc] initWithFrame: CGRectMake(80.0f, 15.0f, [box frame].size.width - 80.0f - 10.0f , 20.0f)];
		[name setFont: [NSClassFromString(@"WebFontCache") createFontWithFamily: @"Helvetica" traits: 0 size: 16.0f]];
		[name setBackgroundColor: [UIView colorWithRed: 0.0f green: 0.0f blue: 0.0f alpha: 0.0f]];
		
		time = [[UITextLabel alloc] initWithFrame: CGRectMake(80.0f, 40.0f, [box frame].size.width - 80.0f - 10.0f , 14.0f)];
		[time setFont: [NSClassFromString(@"WebFontCache") createFontWithFamily: @"Helvetica" traits: 0 size: 12.0f]];
		[time setBackgroundColor: [UIView colorWithRed: 0.0f green: 0.0f blue: 0.0f alpha: 0.0f]];
		
		location = [[UITextLabel alloc] initWithFrame: CGRectMake(80.0f, 60.0f, [box frame].size.width - 80.0f - 30.0f , 20.0f)];
		[location setFont: [NSClassFromString(@"WebFontCache") createFontWithFamily: @"Helvetica" traits: 0 size: 12.0f]];		
		[location setBackgroundColor: [UIView colorWithRed: 0.0f green: 0.0f blue: 0.0f alpha: 0.0f]];
		
		// the maps button
		maps = [[UIPushButton alloc] initWithFrame: CGRectMake([box frame].size.width - 30.0f, 45.0f, 20.0f, 40.0f)];
		[maps setBackground: [UIImage imageNamed: @"button_pin.png"] forState: 0];
		[maps setBackground: [UIImage imageNamed: @"button_pin_push.png"] forState: 1];
		[maps setDrawsShadow: YES];
		[maps setEnabled: YES];
		[maps setStretchBackground: NO];
		[maps setTapDelegate: self];
		
		// a progress hud (loading flickr images can take some time...)
		progress = [[UIProgressHUD alloc] initWithWindow: self];		
		[progress setText: @"Loading..."];
		
		// add to the box
		[box addSubview: webView];
		[box addSubview: icon];
		[box addSubview: name];
		[box addSubview: time];
		[box addSubview: location];		
		[box addSubview: maps];
		
		// add box to scroller 
		[scrollView addSubview: box];
		
		// add navigation bars
		topBar = [[UINavigationBar alloc] initWithFrame: 
			CGRectMake(0.0f, 0.0f, rect.size.width, 44.0f)];
		[topBar setBarStyle: 2];
		[topBar setDelegate: self];
		[topBar showLeftButton: @"back" withStyle: 2 rightButton: nil withStyle: 0];
		
		// and a label
		UITextLabel *label = [[[UITextLabel alloc] initWithFrame: 
			CGRectMake(0.0f, 0.0f, rect.size.width, 44.0f)] autorelease];
		[label setText: @"juhu"];
		[label setBackgroundColor: [UIView colorWithRed: 0.0f green: 0.0f blue: 0.0f alpha: 0.0f]];
		[label setColor: [UIView colorWithRed: 1.0f green: 1.0f	blue: 1.0f alpha: 1.0f]];
		[label setCentersHorizontally: YES];
		
		// add as subviews		
		[self addSubview: scrollView];
		[self addSubview: topBar];

		// button bar for all the actions
		NSDictionary *page = [NSDictionary dictionaryWithObjectsAndKeys: 
			@"home_long.png", kUIButtonBarButtonInfo, 
			[NSNumber numberWithUnsignedInt: 1], kUIButtonBarButtonTag, 
			self, kUIButtonBarButtonTarget,
			@"gotoPostPage:", kUIButtonBarButtonAction, 
			[NSNumber numberWithFloat: 100.0], kUIButtonBarButtonTitleWidth, nil];

		NSDictionary *comment = [NSDictionary dictionaryWithObjectsAndKeys: 
			@"write_long.png", kUIButtonBarButtonInfo, 
			[NSNumber numberWithUnsignedInt: 2], kUIButtonBarButtonTag, 
			self, kUIButtonBarButtonTarget,
			@"comment:", kUIButtonBarButtonAction, nil];

		NSDictionary *add = [NSDictionary dictionaryWithObjectsAndKeys: 
			@"add_long.png", kUIButtonBarButtonInfo, 
			[NSNumber numberWithUnsignedInt: 3], kUIButtonBarButtonTag, 
			self, kUIButtonBarButtonTarget,
			@"addContact:", kUIButtonBarButtonAction, nil];
		
		NSDictionary *remove = [NSDictionary dictionaryWithObjectsAndKeys: 
			@"remove_long.png", kUIButtonBarButtonInfo, 
			[NSNumber numberWithUnsignedInt: 4], kUIButtonBarButtonTag, 
			self, kUIButtonBarButtonTarget,
			@"removeContact:", kUIButtonBarButtonAction, nil];
		
		NSDictionary *trash = [NSDictionary dictionaryWithObjectsAndKeys: 
			@"trash_long.png", kUIButtonBarButtonInfo, 
			[NSNumber numberWithUnsignedInt: 5], kUIButtonBarButtonTag, 
			self, kUIButtonBarButtonTarget,
			@"trash:", kUIButtonBarButtonAction, nil];

		NSArray *items = [NSArray arrayWithObjects: page, comment, add, remove, trash, nil];
		buttonBar = [[UIButtonBar alloc] initInView: self 
			withFrame: CGRectMake(0.0f, [self frame].size.height - 30.0f, [self frame].size.width, 30.0f) withItemList: items];
		[buttonBar setBarStyle: 2];

		int buttonsBasic[2] = {1,2};
		[buttonBar registerButtonGroup: kSmcButtonBarBasic withButtons: buttonsBasic withCount: 2];
		
		int buttonsAdd[3] = {1,2,3};
		[buttonBar registerButtonGroup: kSmcButtonBarAdd withButtons: buttonsAdd withCount: 3];
		
		int buttonsRemove[3] = {1,2,4};
		[buttonBar registerButtonGroup: kSmcButtonBarRemove withButtons: buttonsRemove withCount: 3];
		
		int buttonsTrash[3] = {1,2,5};
		[buttonBar registerButtonGroup: kSmcButtonBarTrash withButtons: buttonsTrash withCount: 3];
	}
	
	return self;
}

#pragma mark Set and get and action

- (void) setJaikuObject: (smcJaikuAPI *) obj
{
	if (_jaiku != obj)
	{
		[_jaiku release];
		_jaiku = [obj retain];
	}
}

- (void) setContent: (NSDictionary *) new
{
	[_content release];
	_content = [new retain];
	
	// which button bar to show
	if (([[_jaiku username] isEqualToString: [_content objectForKey: kSmcEntryKeyNick]])
		&& ([_jaiku canDelete: [_content objectForKey: kSmcEntryKeyURL]]))
		[buttonBar showButtonGroup: kSmcButtonBarTrash withDuration: 0.1f];
	else if ([[_jaiku username] isEqualToString: [_content objectForKey: kSmcEntryKeyNick]])
		[buttonBar showButtonGroup: kSmcButtonBarBasic withDuration: 0.1f];
	else if ([_jaiku isFriend: [_content objectForKey: kSmcEntryKeyNick]])
		[buttonBar showButtonGroup: kSmcButtonBarRemove withDuration:0.1f];
	else
		[buttonBar showButtonGroup: kSmcButtonBarAdd withDuration:0.1f];
	
	// for making the box the right hight - reset first, rest happens in delegate
	[box setAlpha: 0.0f];
	[box setFrame: CGRectMake (20.0f, 50.0f, [scrollView frame].size.width - 40.0f, 200.0f)];
	CGRect r = [webView frame];
	r.size.height = 120.0f;
	[webView setFrame: r];	
	r = [[[[[webView webView] mainFrame] frameView] documentView] frame];
	r.size.height = 100.0f;
	[[[[[webView webView] mainFrame] frameView] documentView] setFrame: r];

	// start progress indicator
	[progress show: YES];
	
	// bring in the actual content
	[webView loadHTMLString: [_content objectForKey: kSmcEntryKeyText] baseURL: nil];
	[icon setImage: [_content objectForKey: kSmcEntryKeyUserImage]];
	[name setText: [NSString stringWithFormat: @"%@ (%@)", [_content objectForKey: kSmcEntryKeyFirstName],
		[_content objectForKey: kSmcEntryKeyNick]]];
	[time setText: [_content objectForKey: kSmcEntryKeyRelativeDateString]];
	[location setText: [NSString stringWithFormat: @"%@", [_content objectForKey: kSmcEntryKeyLocation]]];

	// maps button or not?
	if ([[_content objectForKey: kSmcEntryKeyLocation] length] >= 2)
		[maps setAlpha: 1.0f];
	else
		[maps setAlpha: 0.0f];
}

- (NSDictionary *) content;
{
	return _content;
}

- (void) gotoPostPage: (id) sender
{
	// open the url for the post
	[(UIApplication *) [self delegate] openURL: [_content objectForKey: kSmcEntryKeyURL]];
}

- (void) addContact: (id) sender
{
	// okay, there we go... no questions, no errors
	[_jaiku addAsFriend: [_content objectForKey: kSmcEntryKeyNick]];	
	// and update...
	if ([[self delegate] respondsToSelector: @selector(update:)])
		[[self delegate] performSelector: @selector(update:) withObject: self];
}

- (void) removeContact: (id) sender
{
	// ask first, sheet delegate will do actual removal
	UIAlertSheet *alertSheet = [[UIAlertSheet alloc] initWithTitle: @"Really remove"
		buttons: [NSArray arrayWithObjects: @"Yes", @"No", nil]
		defaultButtonIndex: 1 
		delegate: self
		context: nil];
	
	[alertSheet setTag: 1];
	[alertSheet setBodyText: 
		[NSString stringWithFormat: @"Should %@ really be removed from your contacts?", [_content objectForKey: kSmcEntryKeyNick]]];
	[alertSheet popupAlertAnimated: YES];
}

- (void) comment: (id) sender
{
	// go the the write view (smcMainView), current post given as 3rd entry in array
	if ([[self delegate] respondsToSelector: @selector(animateFromTo:)])
		[[self delegate] performSelector: @selector(animateFromTo:) withObject: 
			[NSArray arrayWithObjects: self, [NSNumber numberWithInt: 1], _content, nil]];
}

- (void) trash: (id) sender
{
	// ask if really delete
	UIAlertSheet *alertSheet = [[UIAlertSheet alloc] initWithTitle: @"Really Delete"
		buttons: [NSArray arrayWithObjects: @"Yes", @"No", nil]
		defaultButtonIndex: 1 
		delegate: self
		context: nil];
	
	[alertSheet setTag: 0];
	[alertSheet setBodyText: @"Do you want to delete this post?"];
	[alertSheet popupAlertAnimated: YES];
}

#pragma mark Navigation bar delegate

- (void)navigationBar: (UINavigationBar*) bar buttonClicked: (int) button 
{
	// only top bar with one button, call delegate for going back
	if ([[self delegate] respondsToSelector: @selector(animateFromTo:)])
		[[self delegate] performSelector: @selector(animateFromTo:) withObject: 
			[NSArray arrayWithObjects: self, [NSNumber numberWithInt: 0], nil]];
}

#pragma mark Alert sheet delegate

- (void)alertSheet:(UIAlertSheet*)sheet buttonClicked:(int)button
{
	[sheet dismiss];
	
	if ([sheet tag] == 0)
	{
		// delete post sheet
		if (button == 1)
		{
			// really delete, let the app controller do that, expects url
			id error = nil;
			if ([[self delegate] respondsToSelector: @selector(deleteSomething:)])
				error = [[self delegate] performSelector: @selector(deleteSomething:) withObject: 
					[_content objectForKey: kSmcEntryKeyURL]];
			
			// if deleted update and go back
			if (error == nil)
			{
				if ([[self delegate] respondsToSelector: @selector(update:)])
					[[self delegate] performSelector: @selector(update:) withObject: self];
				
				if ([[self delegate] respondsToSelector: @selector(animateFromTo:)])
					[[self delegate] performSelector: @selector(animateFromTo:) withObject: 
						[NSArray arrayWithObjects: self, [NSNumber numberWithInt: 0], nil]];
			} else
			{
			
				UIAlertSheet *alertSheet = [[UIAlertSheet alloc] initWithTitle: @"Sorry"
					buttons: nil
					defaultButtonIndex: 0 
					delegate: nil
					context: nil];
				
				[alertSheet setBodyText: @"Could not delete this post."];
				[alertSheet popupAlertAnimated: YES];
			}
		}		
	} else if ([sheet tag] == 1)
	{
		// remove contact sheet
		if (button == 1)
		{
			// okay, remove her or him...
			[_jaiku removeFriend: [_content objectForKey: kSmcEntryKeyNick]];
			
			// .. and update
			if ([[self delegate] respondsToSelector: @selector(update:)])
				[[self delegate] performSelector: @selector(update:) withObject: self];
		}
		
	}
}

#pragma mark image view (icon) tap delegate

- (BOOL)view:(id)view handleTapWithCount: (int) count event: (struct __GSEvent *) event
{
	if (view == icon)
	{
		// user page jaiku
		[(UIApplication *) [self delegate] openURL: 
			[NSURL URLWithString: 
				[NSString stringWithFormat: @"http://%@.jaiku.com", [_content objectForKey: kSmcEntryKeyNick]]]];
	} else if (view == maps)
	{
		// try google maps
		NSMutableString *l = [NSMutableString stringWithString: [_content objectForKey: kSmcEntryKeyLocation]];
		if ([l length] > 0)
		{
			//replace space
			[l replaceOccurrencesOfString: @" " withString: @"+" options: 0 range: NSMakeRange (0, [l length])];
			// built url
			NSString *urlString = [NSString stringWithFormat: @"http://maps.google.com/maps?q=%@", l];
			// and go for it
			[(UIApplication *) [self delegate] openURL: [NSURL URLWithString: urlString]];
		}
	}
	
	return YES;	
}

#pragma mark web view delegates

// WebView policy delegate for navigation 
- (void)webView:(WebView *)sender decidePolicyForNavigationAction:(NSDictionary *)actionInformation 
	request:(NSURLRequest *)request frame:(WebFrame *)frame decisionListener: (id)listener
{
	// open links in safari
	// check if link... 
	// WebActionNavigationTypeKey: 0 means WebNavigationTypeLinkClicked
	// compile warning are okay, some header (for protocols) are missing - > only id...
	
	if ([[actionInformation objectForKey: @"WebActionNavigationTypeKey"] intValue] == 0)
	{	
		[(UIApplication *) [self delegate] openURL: [request URL]];
		[listener ignore];
	} else
		[listener use];

}

// WebView frame load delegate
- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame
{
	// adjust sizes...
	[UIView beginAnimations: nil];
	[UIView setAnimationDuration: 0.1f];	
	
	float actualDocHeight = [[[frame frameView] documentView] frame].size.height;

	CGRect rect = [box frame];
	rect.size.height = actualDocHeight + 85.0f + 15.0f;
	[box setFrame: rect];
	[box setNeedsDisplay];
	
	// adjust height to fit content exactly
	rect = [webView frame];
	rect.origin.y = 85.0f; 
	rect.size.height = actualDocHeight - 10.0f;
	[webView setFrame: rect];
	
	[webView setNeedsDisplay];
	
	// tell the scroller
	[scrollView setContentSize: CGSizeMake([box frame].size.width, [box frame].size.height + [box frame].origin.y)];

	// and scroll to top
	[scrollView scrollPointVisibleAtTopLeft: CGPointMake(0.0f, 0.0f)];
	
	[box setAlpha: 1.0f];
	[UIView endAnimations];
	
	// stop progress indicator
	[progress show: NO];
}

@end
